#ifndef GRAPHICALUSERINTERFACE_H
#define GRAPHICALUSERINTERFACE_H

#include "FreeTypeFontSystem.h"

namespace Gui
{
	struct Vertex
	{
		Vector3 position;
		Vector2 texcoord;
		unsigned int color;
	};

	enum EWidgetType
	{
		WT_WIDGET,
		WT_BUTTON,
		WT_TEXTFIELD,
	};

	enum EButtonType
	{
		BASIC_TOWER_SELECT = 0,
		SLOWING_TOWER_SELECT,
		START_GAME,
		QUIT_GAME
	};

	class Widget
	{
	public:
		Widget(EWidgetType type);

		EWidgetType GetType() const;
		float GetX() const;
		float GetY() const;
		float GetWidth() const;
		float GetHeight() const;

		float GetTX() const;
		float GetTY() const;
		float GetTW() const;
		float GetTH() const;

		Vector2 GetTextPosition() const;
		void SetTextPosition(Vector2 pos);

		void SetX(float x);
		void SetY(float y);
		void SetWidth(float width);
		void SetHeight(float height);
		void SetVisible(bool visible);

		void SetTX(float tx);
		void SetTY(float ty);
		void SetTW(float tw);
		void SetTH(float th);
		void SetTexcoords(float tx, float ty, float tw, float th);


		bool IsVisible() const;
		bool IsEnabled() const;
		bool IsDirty() const;

		void Clean();

		virtual bool IsInside(int x, int y);

	protected:
		EWidgetType m_type;
		float m_x, m_y;
		float m_tx, m_ty, m_tw, m_th;
		float m_width, m_height;

		Vector2 m_text_position;

		bool m_visible;
		bool m_enabled;
		bool m_dirty;
	};

	class Button : public Widget
	{
	public:
		Button();

		bool IsInside(int x, int y);

		unsigned int GetColor() const;
		void SetColor(unsigned int color);
		String GetText() const;
		void SetText(const String& text);
		void SetFontId(const FontId& id);
		void SetFontSize(unsigned int font_size);
		unsigned int GetFontSize() const;
		FontId GetFontId() const;

		void SetButtonType(EButtonType type);
		EButtonType GetButtonType();

	private:
		unsigned int m_color;
		String m_text;
		FontId m_font_id;
		unsigned int m_font_size;
		EButtonType m_button_type;
	};

	class Textfield : public Widget
	{
	public:
		Textfield();

		unsigned int GetColor() const;
		void SetColor(unsigned int color);
		String GetText() const;
		void SetText(const String& text);
		void SetFontId(const FontId& id);
		void SetFontSize(unsigned int font_size);
		unsigned int GetFontSize() const;
		FontId GetFontId() const;

	private:
		unsigned int m_color;
		String m_text;
		FontId m_font_id;
		unsigned int m_font_size;

	};
}; // namespace gui

namespace Text
{
	struct Vertex
	{
		Vector3 position;
		Vector2 texcoord;
		unsigned int color;
	};
};// namespace Text

class ResourceManager;
class GuiManager
{
public:
	GuiManager(class RenderSystem* render_system, class MessageSystem* message_system, ResourceManager* resource_manager);
	~GuiManager();

	bool Init(int width, int height, unsigned int max_vertices = 1024);
	void Shut();
	void Update();
	void Render();

	void AttachWidget(Gui::Widget* widget);
	void DetachWidget(Gui::Widget* widget);

	FontId LoadFont(const String& filename);

	void ClearAllWidgets();
private:
	void OnMouseMove(IEvent* event);
	void OnMouseButton(IEvent* event);

private:
	void FillButton(Gui::Widget* widget, Gui::Vertex* vertices, unsigned int size, unsigned int& pos);
	void FillTextfield(Gui::Widget* widget, Gui::Vertex* vertices, unsigned int size, unsigned int& pos);

private:
	class RenderSystem* m_render_system;
	class MessageSystem* m_message_system;

	FontBuilder m_font_builder;
	RasterizerState m_rasterizer;
	DepthState m_depth;

	Texture* m_button_icons;

	int m_width, m_height;

	std::vector<Gui::Widget*> m_widgets;
	struct
	{
		Shader m_shader;
		Renderable m_renderable;
		unsigned int m_max_vertices;
		Gui::Vertex* m_vertices;
	} m_gui;

	struct
	{
		Shader m_shader;
		Texture m_texture;
		Renderable m_renderable;
		unsigned int m_max_vertices;
		Text::Vertex* m_vertices;
	} m_font;

};

#endif